/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.metadata.rtcustomization.serverwebapi;

import com.inspur.edp.lcm.metadata.api.entity.*;
import com.inspur.edp.lcm.metadata.common.configuration.MetadataTypeHelper;
import com.inspur.edp.lcm.metadata.inner.api.BoService;
import com.inspur.edp.lcm.metadata.inner.api.utils.BoUtils;
import com.inspur.edp.metadata.rtcustomization.api.CustomizationRtService;
import com.inspur.edp.metadata.rtcustomization.api.entity.CacheModeEnum;
import com.inspur.edp.metadata.rtcustomization.api.entity.DimensionExtendEntity;
import com.inspur.edp.metadata.rtcustomization.api.entity.DimensionExtendEntityDto;
import com.inspur.edp.metadata.rtcustomization.api.entity.DimensionExtendRelation;
import com.inspur.edp.metadata.rtcustomization.common.EnvironmentContext;
import com.inspur.edp.metadata.rtcustomization.common.MetadataCustomizationUtils;
import com.inspur.edp.metadata.rtcustomization.serverapi.CustomizationRtServerService;
import com.inspur.edp.metadata.rtcustomization.serverapi.CustomizationServerService;
import io.iec.edp.caf.commons.utils.CollectionUtils;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import org.springframework.util.StringUtils;

import java.util.Objects;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhaoleitr
 */
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public class CustomizationService4WebApiImp {
    private CustomizationServerService customService;
    private CustomizationRtServerService customRtService;
    private CustomizationServerService getCustomService(){
        if(customService==null){
            customService=SpringBeanUtils.getBean(CustomizationServerService.class);
        }
        return customService;
    }
    private CustomizationRtServerService getCustomRtService(){
        if(customRtService==null){
            customRtService=SpringBeanUtils.getBean(CustomizationRtServerService.class);
        }
        return customRtService;
    }

    /**
     * @return com.inspur.edp.lcm.metadata.api.entity.GspMetadata
     * @Author Robin
     * @Description 运行时获取元数据
     * @Date 10:01 2019/8/20
     * @Param [metadataID]
     **/
    @GET
    @Path(value = "/{id}")
    public MetadataDto getMetadata(@PathParam("id") String id) {
        return getCustomService().getMetadataDto(id);
    }

    /**
     * @return com.inspur.edp.lcm.metadata.api.entity.GspMetadata
     * @Author sunhongfei01
     * @Description 运行时获取元数据
     * @Date 2021-8-30
     * @Param [metadataID]
     **/
    @GET
    @Path(value = "/rt/{id}")
    public MetadataDto getRtMetadata(@PathParam("id") String id) {
        return getCustomRtService().getMetadataDto(id);
    }

    /***
     * @author zhongchq
     * @param metadataTypes 获取元数据的类型
     * @exception RuntimeException
     * @return java.util.List<com.inspur.edp.lcm.metadata.api.entity.Metadata4Ref>
     **/
    @GET
    public List<Metadata4RefDto> getMetadataList(@QueryParam(value = "metadataTypes") String metadataTypes) {
        List<Metadata4Ref> metadatas = getCustomService().getMetadataInfoListWithTypes(metadataTypes);
        MetadataCustomizationUtils utils = new MetadataCustomizationUtils();
        return utils.buildMetadata4RefDto(metadatas);
    }

    @GET
    @Path(value = "/root/dimensions")
    public MetadataDto getMetadataWithRootMdIdAndDimensions(@QueryParam(value = "rootMetadataId") String rootMetadataId,
                                                     @QueryParam(value = "rootMetadataCertId") String rootMetadataCertId,
                                                     @QueryParam(value = "firstDimension") String firstDimension,
                                                     @QueryParam(value = "secondDimension") String secondDimension) {
        return getCustomService().getMetadataWithRootMdIdAndDimensions(rootMetadataId,rootMetadataCertId,firstDimension,secondDimension);
    }

    /**
     * @param metadataTypes 元数据类型
     * @return 元数据信息列表
     */
    @GET
    @Path(value = "helper")
    public List<Metadata4RefDto> getMetadataListForHelp(@QueryParam(value = "metadataTypes") String metadataTypes) {
        List<Metadata4Ref> metadatas = getCustomService().getMetadataInfoListWithTypes(metadataTypes);
        if (metadatas == null || metadatas.size() <= 0) {
            return null;
        }
        MetadataCustomizationUtils utils = new MetadataCustomizationUtils();
        List<Metadata4RefDto> dtoList = utils.buildMetadata4RefDto(metadatas);

        Map<String, String> boInfo = null;
        BoService boService = BoUtils.getBoService();
        if(Objects.nonNull(boService)){
            boInfo = boService.getId2NameMap();
        }
        for(Metadata4RefDto item : dtoList){
            if (boInfo != null && boInfo.containsKey(item.getMetadata().getBizobjectID())) {
                item.getMetadata().setBizobjectID(boInfo.get(item.getMetadata().getBizobjectID()));
            }
        }

        List<MetadataType> typesList = getMetadataTypeList();
        Map<String, String> typeInfo = new HashMap<>();
        typesList.forEach(item -> typeInfo.put(item.getTypeCode(), item.getTypeName()));


        dtoList.forEach(item -> {
            if (typeInfo.containsKey(item.getMetadata().getType())) {
                item.getMetadata().setType(typeInfo.get(item.getMetadata().getType()));
            }
        });

        return dtoList;
    }

    /**
     * @return 元数据信息列表
     */
    @GET
    @Path(value = "packaged")
    public List<Metadata4RefDto> getPackagedMetadataInfo() {
        List<Metadata4Ref> metadatas = getCustomService().getAllPackagedMetadataInfo();
        MetadataCustomizationUtils utils = new MetadataCustomizationUtils();
        return utils.buildMetadata4RefDto(metadatas);
    }

    /**
     * @param metadataTypes 元数据类型
     * @return 元数据信息列表
     */
    @GET
    @Path(value = "packaged")
    public List<Metadata4RefDto> getPackagedMetadataInfoWithTypes(@QueryParam(value = "metadataTypes") String metadataTypes) {
        List<Metadata4Ref> metadatas = getCustomService().getAllPackagedMetadataInfoWithTypes(metadataTypes);
        MetadataCustomizationUtils utils = new MetadataCustomizationUtils();
        return utils.buildMetadata4RefDto(metadatas);
    }

    /**
     * @param metadataTypes 元数据类型
     * @return 元数据信息列表
     */
    @GET
    @Path(value = "origin")
    public List<Metadata4RefDto> getAllOriginMdInfoWithTypes(@QueryParam(value = "metadataTypes") String metadataTypes) {
        List<Metadata4Ref> metadatas = getCustomService().getAllOriginMdInfoWithTypes(metadataTypes);
        MetadataCustomizationUtils utils = new MetadataCustomizationUtils();
        return utils.buildMetadata4RefDto(metadatas);
    }

    /**
     * 根据过滤条件获取元数据列表
     *
     * @param filter 元数据过滤
     * @return 元数据信息列表
     */
    @GET
    @Path(value = "filter")
    public List<Metadata4RefDto> getMetadataInfoByFilter(MetadataRTFilter filter) {
        List<Metadata4Ref> metadatas = getCustomService().getMetadataInfoByFilter(filter);
        MetadataCustomizationUtils utils = new MetadataCustomizationUtils();
        return utils.buildMetadata4RefDto(metadatas);
    }

    /**
     * 保存扩展元数据
     */
    @POST
    public boolean saveExtMetadataWithDimensions(DimensionExtendEntityDto dimExtEntityDto) {
        return getCustomService().saveExtMetadataWithDimensions(dimExtEntityDto);
    }

    /**
     * 删除扩展的元数据
     */
    @PUT
    public void deleteExtMetadata(@QueryParam(value = "metadataId") String metadataId,
                                  @QueryParam(value = "certId") String certId) {
        getCustomService().deleteExtMetadata(metadataId, certId);
    }

    /**
     * 根据维度获取元数据
     */
    @GET
    @Path(value = "/dimensions")
    public MetadataDto getMetadataWithDimensions(@QueryParam(value = "basicMetadataId") String basicMetadataId,
                                                 @QueryParam(value = "basicMetadataCertId") String basicMetadataCertId,
                                                 @QueryParam(value = "firstDimension") String firstDimension,
                                                 @QueryParam(value = "secondDimension") String secondDimension) {
        return getCustomService().getMetadataWithDimensions(basicMetadataId, basicMetadataCertId, firstDimension, secondDimension);
    }

    @GET
    @Path(value = "/validation")
    public boolean isExistExtendObjectWithDims(@QueryParam(value = "basicMetadataId") String basicMetadataId,
                                               @QueryParam(value = "basicMetadataCertId") String basicMetadataCertId,
                                               @QueryParam(value = "firstDimension") String firstDimension,
                                               @QueryParam(value = "secondDimension") String secondDimension) {
        return getCustomService().isExistExtendObjectWithDims(basicMetadataId, basicMetadataCertId, firstDimension, secondDimension);
    }

    @GET
    @Path(value = "/basic")
    public MetadataDto getBasicMetadataByExtMdId(@QueryParam(value = "metadataId") String metadataId,
                                                 @QueryParam(value = "certId") String certId) {
        return getCustomService().getBasicMetadataByExtMdId(metadataId, certId);
    }

    @POST
    @Path(value = "/release")
    public boolean releaseMetadataToRt(@QueryParam(value = "metadataId") String metadataId,
                                       @QueryParam(value = "certId") String certId) {
        return getCustomService().releaseMetadataToRt(metadataId, certId);
    }

    @GET
    @Path(value = "/extendinfo")
    public List<DimensionExtendEntityDto> getMetadataInfoRecusively(@QueryParam(value = "basicMetdataID") String basicMetdataID,
                                                                    @QueryParam(value = "basicMetadataCertId") String basicMetadataCertId) {
        List<DimensionExtendEntity> dimensionExtendEntities=  getCustomService().getMetadataInfoListRecusively(basicMetdataID, basicMetadataCertId);
        if(CollectionUtils.isEmpty(dimensionExtendEntities)){
            return null;
        }else {
            return new MetadataCustomizationUtils().buildDimensionExtendEntityDto(dimensionExtendEntities);
        }
    }

    @GET
    @Path(value = "/dimextrelation")
    public DimensionExtendRelation getDimExtRelationByExtMetadata(@QueryParam(value = "metadataId") String metadataId,
                                                                  @QueryParam(value = "certId") String certId) {
        return getCustomService().getDimExtRelationByExtMetadata(metadataId, certId);
    }

    @GET
    @Path(value = "/typeList")
    public List<MetadataType> getMetadataTypeList() {
        return MetadataTypeHelper.getInstance().getMetadataTypes();
    }

    @GET
    @Path(value = "/clearCache")
    public void clearCache(@QueryParam(value = "metadataIds") String metadataIds) {
        if (StringUtils.isEmpty(metadataIds)) {
            return;
        }
        getCustomService().removeCacheByMetadataIds(Arrays.asList(metadataIds.split(",")));
    }

    @GET
    @Path(value = "/clearAllCache")
    public void clearAllCache() {
        getCustomService().clearAllCache();
    }

    @GET
    @Path(value = "/root/dynamic")
    public MetadataDto getDynamicMetadata(
        @QueryParam(value = "rootMetadataId") String rootMetadataId,
        @QueryParam(value = "rootMetadataCertId") String rootMetadataCertId,
        @QueryParam(value = "firstDimensionValue") String firstDimensionValue,
        @QueryParam(value = "secondDimensionValue") String secondDimensionValue){
        return getCustomService().getDynamicMetadataWithRootMdIdAndDimensions(rootMetadataId, rootMetadataCertId, firstDimensionValue, secondDimensionValue);
    }
}
